package common.util;

import common.model.compare.BaseCompare;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 注意需要重写 T 类中的 equals 和 hashCode 方法
 *
 * @author 米泽鹏
 */
public class CompareUtil {

	private CompareUtil() {
		throw new AssertionError("不可实例化");
	}

	/**
	 * 比较两个list是否完全相同
	 *
	 * @param thisList 待比较的list之一
	 * @param thatList 待比较的list之二
	 * @param <T>      T extends BaseCompare
	 * @return boolean
	 */
	public static <T extends BaseCompare> boolean equals(List<T> thisList, List<T> thatList) {
		NullChecker.throwExceptionIfAnyNull(thisList, thatList);
		if (thisList == thatList) {
			return true;
		}
		if (thisList.size() != thatList.size()) {
			return false;
		}
		for (T thisOne : thisList) {
			if (!thatList.contains(thisOne)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 适合多对多关联关系的比较
	 * <br/>
	 * 获取需要删除的记录的id的list
	 *
	 * @param currentIdList     数据库当前记录的id集合
	 * @param destinationIdList 变更后的记录的id集合
	 * @return List<Long>
	 */
	public static List<Long> getDeleteIdList(List<Long> currentIdList, List<Long> destinationIdList) {
		NullChecker.throwExceptionIfAnyNull(currentIdList, destinationIdList);
		return currentIdList.stream().filter(id -> !destinationIdList.contains(id)).collect(Collectors.toList());
	}

	/**
	 * 适合多对多关联关系的比较
	 * <br/>
	 * 获取需要新增的记录的id的list
	 *
	 * @param currentIdList     数据库当前记录的id集合
	 * @param destinationIdList 变更后的记录的id集合
	 * @return List<Long>
	 */
	public static List<Long> getInsertIdList(List<Long> currentIdList, List<Long> destinationIdList) {
		NullChecker.throwExceptionIfAnyNull(currentIdList, destinationIdList);
		return destinationIdList.stream().filter(id -> !currentIdList.contains(id)).collect(Collectors.toList());
	}

	/**
	 * 获取需要新增的记录的list
	 *
	 * @param currentList     数据库当前的记录
	 * @param destinationList 变更后的记录
	 * @param <T>             T 为 BaseCompare 的子类
	 * @return List<T>
	 */
	public static <T extends BaseCompare> List<T> getInsertList(List<T> currentList, List<T> destinationList) {
		NullChecker.throwExceptionIfAnyNull(currentList, destinationList);
		return destinationList.stream().filter(item -> !currentList.contains(item)).collect(Collectors.toList());
	}

	/**
	 * 获取需要删除的记录的id的list
	 *
	 * @param currentList     数据库当前的记录
	 * @param destinationList 变更后的记录
	 * @param <T>             T 为 BaseCompare 的子类
	 * @return List<Long>
	 */
	public static <T extends BaseCompare> List<Long> getDeleteIdListFromEntity(List<T> currentList, List<T> destinationList) {
		return getDeleteList(currentList, destinationList).stream().map(BaseCompare::getId).collect(Collectors.toList());
	}

	/**
	 * 获取需要删除的记录的list
	 *
	 * @param currentList     数据库当前的记录
	 * @param destinationList 变更后的记录
	 * @param <T>             T 为 BaseCompare 的子类
	 * @return List<T>
	 */
	public static <T extends BaseCompare> List<T> getDeleteList(List<T> currentList, List<T> destinationList) {
		NullChecker.throwExceptionIfAnyNull(currentList, destinationList);
		return currentList.stream().filter(item -> !destinationList.contains(item)).collect(Collectors.toList());
	}

}
